<?php
/**
 * Installation tool.
 *
 * @author Martin "DevelX" Jurča
 * @version 2009-10-20
 */
class Installer {
    private $smarty;
    private $language;
    private $config;
    private $path;

    public function __construct() {
        if (!isset($_SESSION['charset'])) {
            $_SESSION['charset'] = 'utf-8';
        }
        header('Content-Type: text/html; charset=' . $_SESSION['charset']);
        $this->config = isset($_SESSION['config']) ? $_SESSION['config'] :
                array();
        $this->path = dirname(__FILE__);
        $result = true;
        if (isset($_POST['step'])) {
            $result = $this->{"installStep{$_POST['step']}"}();
        }
        $this->loadLanguage();
        if (!is_writable('cache/smarty')) {
            echo $this->lang('smartyCompilerErr');
            return;
        }
        require_once 'libs/smarty/Smarty.class.php';
        $this->smarty = new Smarty();
        $this->smarty->template_dir = '';
        $this->smarty->compile_dir = 'cache/smarty';
        $this->smarty->config_dir = 'libs/smarty/configs';
        if (!array_key_exists('installStep', $_SESSION)) {
            $_SESSION['installStep'] = 0;
        }
        $params = $this->{"getDisplayParameters" .
                "{$_SESSION['installStep']}"}($result);
        $this->smarty->assign($params);
        $this->smarty->display('install/templates/layout.tpl');
        $_SESSION['config'] = $this->config;
    }

    private function getDisplayParameters6($result) {
        $params = array('step' => 6, 'title' => $this->lang('title'),
                'installSuccess' => $this->lang('installSuccess'));
        return $params;
    }

    private function installStep5() {
        require_once Config::ROOT . '/libs/Cache.php';
        require_once Config::ROOT . '/libs/FTP.php';
        require_once Config::ROOT . '/libs/DBDriver' .
                Config::DATABASE_DRIVER . '.php';
        require_once Config::ROOT . '/libs/DBAPI.php';
        require_once Config::ROOT . '/libs/RecordList.php';
        require_once Config::ROOT . '/modules/Module.php';
        require_once Config::ROOT . '/modules/Modules/Modules.php';
        require_once Config::ROOT . '/libs/smarty/Smarty.class.php';
        Modules::getModule('Users')->install();
        Modules::getModule('Modules')->install();
        Modules::getModule('Log')->install();
        if (Modules::getModule('Repository') !== false) {
            Modules::getModule('Repository')->install();
        }
        Modules::getModule('Files')->install();
        Modules::getModule('View')->install();
        Modules::getModule('HtAccess')->install();

        $this->config['INSTALLED'] = true;
        require_once 'libs/ConfigStorage.php';
        if (!ConfigStorage::save($this->config, '')) {
            return 'configERR';
        }
        $_SESSION['installStep'] = 6;
        return true;
    }

    private function getDisplayParameters5($result) {
        $params = array('step' => 5, 'title' => $this->lang('title'),
                'finalizing' => $this->lang('finalizing'), 'finish' =>
            $this->lang('finish'), 'configERR' => $this->lang(''));
        if ($result !== true) {
            $params['err'] = $this->lang($result);
        }
        return $params;
    }

    private function installStep4() {
        if (!is_writable('config.php') && !@chmod('config.php', 0777)) {
            $ftp = @ftp_connect($this->config['FTP_HOST']);
            if ($ftp === false) {
                return 'configERR';
            }
            @ftp_login($ftp, $this->config['FTP_LOGIN'],
                    $this->config['FTP_PASSWORD']);
            if (!@ftp_chmod($ftp, 0777, $this->config['FTP_DIRECTORY'] .
                    '/config.php')) {
                return 'configERR';
            }
        }
        $this->config['BUGREPORT'] = 'display';
        $this->config['TIMEZONE'] = $_POST['timezone'];
        $this->config['INSTALLED'] = false;
        require_once 'libs/ConfigStorage.php';
        if (!ConfigStorage::save($this->config, '')) {
            return 'configERR';
        }
        $_SESSION['installStep'] = 5;
        return true;
    }

    private function getDisplayParameters4($result) {
        $params = array('step' => 4, 'title' => $this->lang('title'),
                'timezone' => $this->lang('timezone'), 'next' =>
                $this->lang('next'), 'default' => date_default_timezone_get());
        if ($result === false) {
            $params['err'] = $this->lang('incorrectRepositoryURL');
        } elseif ($result !== true) {
            $params['err'] = $this->lang($result);
        }
        return $params;
    }

    private function installStep3() {
        if (!is_numeric($_POST['imageQuality']) ||
                ($_POST['imageQuality'] < 0) ||
                ($_POST['imageQuality'] > 100)) {
            return 'imageQualityNumber';
        }
        if (!is_numeric($_POST['imageBgR']) ||
                !is_numeric($_POST['imageBgG']) ||
                !is_numeric($_POST['imageBgR']) ||
                ($_POST['imageBgR'] < 0) || ($_POST['imageBgR'] > 255) ||
                ($_POST['imageBgG'] < 0) || ($_POST['imageBgG'] > 255) ||
                ($_POST['imageBgB'] < 0) || ($_POST['imageBgB'] > 255)) {
            return 'imageBGNumber';
        }
        if (!is_numeric($_POST['cacheSize']) || ($_POST['cacheSize'] < -1)) {
            return 'cacheSizeNumber';
        }
        if (!is_numeric($_POST['cacheTimeoutDB']) ||
                ($_POST['cacheTimeoutDB'] < -1)) {
            return 'cacheDBNumber';
        }
        if (!is_numeric($_POST['cacheTimeoutIMG']) ||
                ($_POST['cacheTimeoutIMG'] < -1)) {
            return 'cacheIMGNumber';
        }
        if (!is_numeric($_POST['cacheTimeoutOut']) ||
                ($_POST['cacheTimeoutOut'] < -1)) {
            return 'cacheOutNumber';
        }
        $this->config['IMAGE_QUALITY'] = (int) $_POST['imageQuality'];
        $this->config['IMAGE_BACKGROUND_R'] = (int) $_POST['imageBgR'];
        $this->config['IMAGE_BACKGROUND_G'] = (int) $_POST['imageBgG'];
        $this->config['IMAGE_BACKGROUND_B'] = (int) $_POST['imageBgB'];
        $this->config['MAX_CACHE_SIZE'] = (int) $_POST['cacheSize'];
        $this->config['CACHE_DB_TIMEOUT'] = (int) $_POST['cacheTimeoutDB'];
        $this->config['CACHE_OUTPUT_TIMEOUT'] = (int) $_POST['cacheTimeoutOut'];
        $this->config['CACHE_IMAGE_TIMEOUT'] = (int) $_POST['cacheTimeoutIMG'];
        $_SESSION['installStep'] = 4;
        return true;
    }

    private function getDisplayParameters3($result) {
        $params = array('step' => 3, 'imageBackground' =>
                $this->lang('imageBackground'), 'imageQuality' =>
                $this->lang('imageQuality'), 'cacheSize' =>
                $this->lang('cacheSize'), 'dbCacheTimeout' =>
                $this->lang('dbCacheTimeout'), 'imgCacheTimeout' =>
                $this->lang('imgCacheTimeout'), 'outputCacheTimeout' =>
                $this->lang('outputCacheTimeout'), 'next' =>
                $this->lang('next'), 'title' => $this->lang('title'));
        if ($result !== true) {
            $params['err'] = $this->lang($result);
        }
        return $params;
    }

    private function installStep2() {
        if (!preg_match('/^\w+$/', $_POST['dbdriver']) ||
                !file_exists('libs/DBDriver' . $_POST['dbdriver'] . '.php')) {
            return 'incorrectDriver';
        }
        require_once 'libs/DBDriver' . $_POST['dbdriver'] . '.php';
        $driverName = "DBDriver{$_POST['dbdriver']}";
        $access = "{$_POST['dbuser']}:{$_POST['dbpassword']}@" .
                "{$_POST['dbserver']}//{$_POST['dbname']}";
        try {
            $driver = new $driverName($access);
        } catch (Exception $e) {
            return 'dbConnectionFailed' . $e->getMessage();
        }
        $ftp = @ftp_connect($_POST['ftphost']);
        if ($ftp === false) {
            return 'ftpConnectionFailed';
        }
        $login = @ftp_login($ftp, $_POST['ftplogin'], $_POST['ftppassword']);
        if ($login === false) {
            return 'ftpLoginFailed';
        }
        $this->config['DATABASE_DRIVER'] = $_POST['dbdriver'];
        $this->config['DATABASE_ACCESS'] = $access;
        $this->config['FTP_HOST'] = $_POST['ftphost'];
        $this->config['FTP_LOGIN'] = $_POST['ftplogin'];
        $this->config['FTP_PASSWORD'] = $_POST['ftppassword'];
        $this->config['FTP_DIRECTORY'] = preg_replace('/\/+$/', '',
                $_POST['ftpdir']);
        $_SESSION['installStep'] = 3;
        return true;
    }

    private function getDisplayParameters2($result) {
        $params = array('step' => 2, 'dbdriver' => $this->lang('dbdriver'),
                'dbuser' => $this->lang('dbuser'), 'dbpassword' =>
                $this->lang('dbpassword'), 'dbserver' =>
                $this->lang('dbserver'), 'dbname' => $this->lang('dbname'),
                'title' => $this->lang('title'), 'charset' =>
                (isset($_SESSION['charset']) ? $_SESSION['charset'] :
                Config::DEFAULT_CHARSET), 'ftphost' => $this->lang('ftphost'),
                'ftplogin' => $this->lang('ftplogin'), 'ftppassword' =>
                $this->lang('ftppassword'), 'ftpdir' => $this->lang('ftpdir'),
                'next' => $this->lang('next'));
        $drivers = glob('libs/DBDriver*.php');
        foreach ($drivers as &$driver) {
            $driver = substr($driver, strrpos($driver, '/') + 9);
            $driver = substr($driver, 0, strpos($driver, '.'));
        }
        $params['drivers'] = $drivers;
        if ($result !== true) {
            if ((strlen($result) >= 18) &&
                    (substr($result, 0, 18) == 'dbConnectionFailed')) {
                $params['err'] = $this->lang('dbConnectionFailed') .
                        substr($result, 18);
            } else {
                $params['err'] = $this->lang($result);
            }
        }
        return $params;
    }

    private function installStep1() {
        if (!iconv('utf-8', $_POST['charset'], 'abcd')) {
            return false;
        }
        $this->config['DEFAULT_CHARSET'] = $_POST['charset'];
        $this->config['AUTODETECT_SESSION_LANG'] = isset($_POST['detectLang']);
        $this->config['AUTODETECT_SESSION_CHARSET'] =
                isset($_POST['detectCharset']);
        $this->config['DOMAIN_NAME'] = $_POST['domainName'];
        $this->config['ROOT'] = preg_replace('/\/+$/', '', $_POST['rootDir']);
        $this->config['WEB_DIR'] = preg_replace('/\/+$/', '',
                $_POST['webDir']);
        $_SESSION['installStep'] = 2;
        return true;
    }

    private function getDisplayParameters1($result) {
        $params = array('next' => $this->lang('next'), 'defaultCharset' =>
                $this->lang('defaultCharset'), 'detectLang' =>
                $this->lang('detectLang'), 'charset' => 'utf-8',
                'detectCharset' => $this->lang('detectCharset'), 'step' => 1,
                'domainName' => $this->lang('domainName'), 'rootDir' =>
                $this->lang('rootDir'), 'title' => $this->lang('title'),
                'charset' => (isset($_SESSION['charset']) ?
                $_SESSION['charset'] : Config::DEFAULT_CHARSET), 'root' =>
                preg_replace('/^(.*)\\/install$/', '$1', dirname(__FILE__)),
                'webDir' => $this->lang('webDir'), 'webroot' =>
                str_replace('//', '', '/' . preg_replace('/^\/+(.*)\/+$/',
                '$1', $_SERVER['REQUEST_URI'])), 'host' =>
                $_SERVER['HTTP_HOST']);
        $params['err'] = $result ? '' : $this->lang('charsetErr');
        return $params;
    }

    private function installStep0() {
        $_SESSION['language'] = $_POST['lang'];
        $this->config['DEFAULT_LANG'] = $_POST['lang'];
        $_SESSION['installStep'] = 1;
        return true;
    }

    private function getDisplayParameters0($result) {
        $params = array('title' => $this->lang('title'), 'charset' =>
                (isset($_SESSION['charset']) ? $_SESSION['charset'] :
                Config::DEFAULT_CHARSET), 'step' => 0, 'choose' =>
                $this->lang('chooseLanguage'), 'lang' =>
                (isset($_SESSION['language']) ? $_SESSION['language'] :
                Config::DEFAULT_LANG), 'next' => $this->lang('next'));
        $langs = glob($this->path . '/lang/*.php');
        foreach ($langs as &$lang) {
            $lang = substr($lang, strrpos($lang, '/') + 1);
            $lang = substr($lang, 0, strpos($lang, '.'));
        }
        $params['langs'] = $langs;
        return $params;
    }

    private function lang($key) {
        $charset = isset($_SESSION['charset']) ? $_SESSION['charset'] :
                Config::DEFAULT_CHARSET;
        if (array_key_exists($key, $this->language)) {
            return iconv('UTF-8', $charset, $this->language[$key]);
        } else {
            return iconv('UTF-8', $charset, $key);
        }
    }

    private function loadLanguage() {
        $lang = array();
        $langCode = isset($_SESSION['language']) ? $_SESSION['language'] :
                Config::DEFAULT_LANG;
        if (file_exists($this->path . '/lang/' . $langCode . '.php')) {
            require_once $this->path . '/lang/' . $langCode . '.php';
        } elseif ((strlen($langCode) > 2) && file_exists($this->path .
                '/lang/' . substr($langCode, 0, 2) . '.php')) {
            require_once $this->path . '/lang/' . substr($langCode, 0, 2) .
                    '.php';
        } else {
            $langs = glob($this->path . '/lang/*.php');
            if (count($langs) > 0) {
                require_once $langs[0];
            }
        }
        $this->language = $lang;
    }
}
?>
